const { getRoomName, getRoomMaster, getRoomMembers, getUserName } = require("./utils");

const http = require("http");
const express = require("express");
const log4js = require("log4js");
const fs = require("fs");
const { Server } = require("socket.io");
const cors = require("cors");

// 房间的最大用户数
const MAX_USERS = 4;
// 日志配置
log4js.configure({
  appenders: {
    file: {
      type: "file",
      filename: "app.log",
      layout: {
        type: "pattern",
        pattern: "%r %p - %m",
      },
    },
  },
  categories: {
    default: {
      appenders: ["file"],
      level: "debug",
    },
  },
});

const logger = log4js.getLogger();
const app = express();
app.use(express.static("./public"));
// 设置跨域
app.all("*", function (req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Content-Type");
  res.header("Access-Control-Allow-Methods", "DELETE, PUT, POST, GET, OPTIONS");
  if (req.method.toLowerCase() === "options") {
    res.send(200);
  } else {
    next();
  }
});

const http_server = http.createServer(app);

const io = new Server(http_server, {
  cors: {
    origin: "*", // 允许所有域名访问
    methods: ["GET", "POST", "PUT", "DELETE"], // 允许的请求方法
    allowedHeaders: ["Content-Type"], // 允许的请求头
  },
});

const allRooms = [];
const users = [];

io.on("connection", (socket) => {
  /* 注册用户 */
  socket.on("register", data => {
    users.push({ name: data.userName, id: data.socketId });
  })
  /**
   * 接收消息
   * type data {
      roomId: string, // 在哪个房间
      socketId: string, // 谁发言
      type: string,  
      content: string;
    } 
   * */
  socket.on("message", (data) => {
    logger.debug(
      `message, sender: ${getUserName(users, data.socketId)}, room: ${data.roomId}, ${data.content}, type: ${data.type}`
    );
    console.log("发送消息:", data);
    socket
      .to(data.roomId)
      .emit("message", { user: getUserName(users, data.socketId), content: data.content });
  });
  /**
   * 交换RTC信息
   * type data {
      roomId: string, // 发给哪个房间
      content: any, // sdp或ice
    } 
   */
  socket.on("sdp", data => {
    if (data.type) {
      if (data.type === 'offer') {
        socket
          .to(data.roomId)
          .emit("sdp", { type: 'offer', content: data.content });
      } else if (data.type === 'answer') {
        socket
          .to(data.roomId)
          .emit("sdp", { type: 'answer', content: data.content });
      } else if (data.type === 'candidate') {
        socket
          .to(data.roomId)
          .emit("sdp", { type: 'candidate', content: data.content });
      }
    }
  })
  /**
   * 创建/加入房间
   * type data {
      roomId: string,
      userName: string,
      roomName?: string, // 创建房间时有
    }
   */
  socket.on("join", (data) => {
    let isCreate = false;
    let trueRoom = data.roomId; // 要加入的房间id
    console.log("即将加入的房间:", data.roomId, data.userName);
    // 房间id等于socket的id，则为用户创建房间
    if (data.roomId === socket.id) {
      trueRoom = data.roomId + "+0001";
      isCreate = true;
    }

    socket.join(trueRoom);
    console.log("所有房间:", io.sockets.adapter.rooms, allRooms);
    const myRoom = io.sockets.adapter.rooms.get(trueRoom);
    console.log("当前房间:", myRoom);
    const users = myRoom.size;
    logger.debug(`the user number of room (${trueRoom}) is: ${users}`);
    // 房间未满
    if (users < MAX_USERS) {
      if (isCreate) {
        // 创建房间
        allRooms.push({
          name: data.roomName,
          master: data.userName,
          roomId: trueRoom,
          members: [{ name: data.userName, id: socket.id }]
        })
      } else {
        // 加入其他房间
        allRooms.find(item => item.roomId === trueRoom).members.push({ name: data.userName, id: socket.id });
      }
      socket.emit("joined", {
        roomId: trueRoom,
        room: getRoomName(allRooms, trueRoom),
        master: getRoomMaster(allRooms, trueRoom),
        members: getRoomMembers(allRooms, trueRoom)
      });
      if (users > 1) {
        socket
          .to(trueRoom)
          .emit("otherjoin", { roomId: trueRoom, adderName: data.userName });
      }
    } else {
      // 房间满人
      socket.leave(trueRoom);
      socket.emit("full", { room: trueRoom, socketId: socket.id });
    }
  });
  /* 离开房间 */
  socket.on("leave", (room) => {
    socket.leave(room);

    const myRoom = socket.rooms[room];
    var users = myRoom ? Object.keys(myRoom.sockets).length : 0;
    logger.debug("the user number of room is: " + users);
    // 通知其他人
    socket.to(room).emit("bye", { room, socketId: socket.id });
    // 通知用户已完成
    socket.emit("leave", { room, socketId: socket.id });
  });
});

http_server.listen(8888, () => {
  console.log("listening 8888...");
});
